﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Casamiel.API.Application.Models;
using Casamiel.Application;
using Casamiel.Application.Commands;
using Casamiel.Application.Commands.GroupPurchase;
using Casamiel.Application.Commands.Wechat;
using Casamiel.Common;
using Casamiel.Common.Extensions;
using Casamiel.Domain;
using Casamiel.Domain.Entity;
using Casamiel.Domain.Request;
using MediatR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
using PaySharp.Wechatpay;
using PaySharp.Wechatpay.Domain;
using PaySharp.Wechatpay.Request;

namespace Casamiel.API.Application.Services
{
    /// <summary>
    /// All pay service.
    /// </summary>
    public class AllPayService : IAllPayService
    {
        private readonly IMemberCardService _memberCardService;
        private readonly IPaymentService paymentService;
        private readonly IIcApiService _icApiService;
        //private readonly IUserLogService _userLogService;
        private readonly INoticeService _notice;
        private readonly NLog.ILogger logger = LogManager.GetLogger("PayService");
        private readonly IOrderService _order;
        private readonly ICasaMielSession _session;
        private readonly IStoreService _storeService;
        private readonly IStoreApiService _storeApiService;
        private readonly IMallService _mallService;
        private readonly MallSettings _mallSettings;
        private readonly IMediator _mediator;
        private readonly List<Common.MiniAppSettings> _listminiAppSettings;
        private readonly IMemberCouponService _memberCouponService;
        private readonly IMemberCashCouponService _memberCashCouponRepository;
        private IConfiguration Configuration { get; }
        private readonly string _apiname;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="order"></param>
        /// <param name="paymentService">Payment service.</param>
        /// <param name="iicApiService">Iic API service.</param>
        /// <param name="userLog">User log.</param>
        /// <param name="casaMielSession">Casa miel session.</param>
        /// <param name="storeService">Store service.</param>
        /// <param name="storeApiService">Store API service.</param>
        /// <param name="memberCardService"></param>
        /// <param name="mallService"></param>
        /// <param name="snapshot"></param>
        /// <param name="notice">notice</param>
        /// <param name="mediator"></param>
        /// <param name="mini"></param>
        ///<param name="configuration"></param>
        /// <param name="memberCashCouponRepository"></param>
        /// <param name="memberCouponService"></param>
        /// <param name="optionsSnapshot"></param>
        public AllPayService(IOrderService order, IPaymentService paymentService, IIcApiService iicApiService, IUserLogService userLog, ICasaMielSession casaMielSession,
                            IStoreService storeService, IStoreApiService storeApiService, IMemberCardService memberCardService, IMallService mallService,
                            IOptionsSnapshot<MallSettings> snapshot, INoticeService notice, IMediator mediator, IOptionsSnapshot<List<Common.MiniAppSettings>> mini,
                             IConfiguration configuration, IMemberCashCouponService memberCashCouponRepository, IMemberCouponService memberCouponService, IOptionsSnapshot<CasamielSettings> optionsSnapshot)
        {
            if (snapshot == null) {
                throw new ArgumentNullException(nameof(snapshot));
            }

            if (mini == null) {
                throw new ArgumentNullException(nameof(mini));
            }

            this.paymentService = paymentService;
            this._icApiService = iicApiService;
            // this._userLogService = userLog;
            this._session = casaMielSession;
            this._storeService = storeService;
            this._storeApiService = storeApiService;
            _memberCardService = memberCardService;
            _mallService = mallService;
            _mallSettings = snapshot.Value;
            _notice = notice;
            _mediator = mediator;
            _order = order;
            _listminiAppSettings = mini.Value;
            Configuration = configuration;
            _memberCashCouponRepository = memberCashCouponRepository;
            _memberCouponService = memberCouponService;
            _apiname = optionsSnapshot.Value.ApiName;
        }

        /// <summary>
        /// Charges the pay complete.
        /// </summary>
        /// <returns><c>true</c>, if pay complete was charged, <c>false</c> otherwise.</returns>
        /// <param name="tradeNO">商户交易号</param>
        /// <param name="OutTradeNO">OutTradeNO </param>
        /// <param name="PayAmount">Amount.</param>
        /// <param name="MchId"></param>
        public async Task<bool> PayComplete(string tradeNO, string OutTradeNO, double PayAmount, string MchId = "")
        {
            var payrecord = await paymentService.FindAsync<ICasaMielSession>(tradeNO).ConfigureAwait(false);
            //entity.Wait();
            //var payrecord = entity.Result;
            if (payrecord == null) {
                logger.Trace($"交易记录不存在，tradeno:{tradeNO},outtradeno:{OutTradeNO}");
                return false;
            }
            if (payrecord.State == 1) {
                return true;
            }

            double EPSILON = 0.00000001;
            if (Math.Abs(payrecord.Amount - PayAmount) < EPSILON) {
                switch (payrecord.OperationMethod) {
                    case (int)OperationMethod.CardReCharge:
                        try {
                            Zmodel tmodel = await _icApiService.IcCharge(payrecord.BillNO, payrecord.Amount, payrecord.PayMethod, OutTradeNO, MchId, payrecord.ShopId).ConfigureAwait(false);
                            if (tmodel.code == 0 || tmodel.code == 180)// || tmodel.code == 261充值记录失败
                            {
                                if (tmodel.code == 0) {
                                    var rnt = JsonConvert.DeserializeObject<dynamic>(tmodel.content);
                                    payrecord.IcTradeNO = rnt.tradeno;
                                    payrecord.Largessmoney = rnt.largessmoney;
                                    payrecord.PayTime = DateTime.Now;
                                    payrecord.OperationState = 1;
                                    payrecord.OutTradeNo = OutTradeNO;
                                    payrecord.MchId = MchId;
                                    payrecord.State = 1;
                                    payrecord.LastOperationTime = DateTime.Now;
                                    payrecord.LastOperationTime = DateTime.Now;
                                    payrecord.PayTime = DateTime.Now;
                                    //payrecord.Remark = "小程序支付";
                                    //_paymentRecordRepository.Update(payrecord, 0);
                                    await paymentService.UpdateAsync<ICasaMielSession>(payrecord).ConfigureAwait(false);
                                    var logdata = new Domain.UserLog { Url = "", OPInfo = $"会员充值，卡号[{payrecord.BillNO}],金额{payrecord.Amount}", OPTime = DateTime.Now, UserName = payrecord.Mobile };
                                    //await _userLogService.AddAsync<ICasaMielSession>(logdata).ConfigureAwait(false);
                                    await _mediator.Publish(new UserLogNoticeCommand(logdata)).ConfigureAwait(false);
                                    //try {
                                    //    var cmd = new SaveInvoiceDetailCommand(payrecord.Mobile, payrecord.Amount.ToString(CultureInfo.CurrentCulture).ToDecimal(0), OutTradeNO);
                                    //    await _mediator.Send(cmd).ConfigureAwait(false);
                                    //} catch (AggregateException ex) {
                                    //    logger.Error($"{ex.StackTrace}");
                                    //}
                                }
                                return true;
                            } else {
                                if (tmodel.code == 41) {
                                    return false;
                                }
                                Console.WriteLine(tmodel.msg);
                                logger.Error("会员充值失败：" + JsonConvert.SerializeObject(tmodel));

                                await Refund(payrecord).ConfigureAwait(false);

                                return false;
                            }
                        } catch (System.Net.Http.HttpRequestException ex) {
                            logger.Error(ex.StackTrace);
                            return false;
                        }

                    case (int)OperationMethod.CakeStore:
                    case (int)OperationMethod.Waimai://外卖
                    case (int)OperationMethod.Pre://预点单
                        var _cardno = "";
                        var cardlist = await _memberCardService.GetListAsync<ICasaMielSession>(payrecord.Mobile).ConfigureAwait(false);

                        if (cardlist != null && cardlist.Count(c => c.IsBind == true) == 2) {
                            var vipcard = cardlist.SingleOrDefault(c => c.IsBind == true && c.CardType != "3");
                            if (vipcard != null) {
                                _cardno = vipcard.CardNO;
                            }
                        }
                        if (string.IsNullOrEmpty(_cardno)) {
                            foreach (var item in cardlist) {
                                if (item.IsBind) {
                                    _cardno = item.CardNO;
                                    break;
                                }
                            }
                        }

                        payrecord.PayTime = DateTime.Now;
                        payrecord.OperationState = 1;
                        payrecord.OutTradeNo = OutTradeNO;
                        payrecord.MchId = MchId;
                        payrecord.State = 1;
                        payrecord.LastOperationTime = DateTime.Now;

                        // var ordere = await _storeApiService.GetOrderByOrderCodeAsync(payrecord.BillNO, payrecord.Mobile);

                        var order = await _order.GetByOrderCodeAsync<ICasaMielSession>(payrecord.BillNO, payrecord.Mobile).ConfigureAwait(false);
                        if (order == null || order.OrderStatus == 9) {
                            
                            await Refund(payrecord).ConfigureAwait(false);
                        }
                        var storeinfo = await _storeService.GetByStoreIdAsync<ICasaMielSession>(order.StoreId).ConfigureAwait(false);
                        var discountlist = await _order.GetListByOrderBaseId<ICasaMielSession>(order.OrderBaseId).ConfigureAwait(false);
                        var pay = new IcConsumepayReq {
                            Shopid = storeinfo.RelationId,
                            Tradeno = order.IcTradeNO,
                            Phoneno = payrecord.Mobile,
                            Cardno = _cardno,
                            Createinvoice = true
                        };
                        pay.Paycontent = new List<IcConsumepayReq.PaycontentItem>();

                        foreach (var x in discountlist) {
                            var _paytype = "5";

                            if (x.DiscountCouponType == 1) {
                                _paytype = "6";
                                pay.Paycontent.Add(new IcConsumepayReq.PaycontentItem {
                                    Paytype = _paytype,
                                    Paymoney = x.DiscountCouponUseMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                                    Paytradeno = $"t{DateTime.Now.ToString("yyMMddHHmmssffff", CultureInfo.CurrentCulture)}",
                                    Payuser = $"{x.DiscountCouponId}"
                                });
                            } else {

                                if (_apiname == "hgspApi") {
                                    var tlist = _memberCashCouponRepository.GetListAsnyc<ICasaMielSession>(payrecord.Mobile).GetAwaiter().GetResult();
                                    MemberCashCoupon cashentity = tlist.SingleOrDefault(t => t.TicketCode.Contains($"{x.DiscountCouponId}", StringComparison.CurrentCulture));
                                    if (cashentity != null) {
                                        pay.Paycontent.Add(new IcConsumepayReq.PaycontentItem {
                                            Paytype = _paytype,
                                            Paymoney = x.DiscountCouponUseMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                                            Paytradeno = $"t{DateTime.Now.ToString("yyMMddHHmmssffff", CultureInfo.CurrentCulture)}",
                                            Payuser = cashentity.TicketCode
                                        });
                                    }
                                } else {
                                    var coupon = await _memberCouponService.FindAsync<ICasaMielSession>(x.DiscountCouponId).ConfigureAwait(false);
                                    pay.Paycontent.Add(new IcConsumepayReq.PaycontentItem {
                                        Paytype = _paytype,
                                        Paymoney = x.DiscountCouponUseMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                                        Paytradeno = $"t{DateTime.Now.ToString("yyMMddHHmmssffff", CultureInfo.CurrentCulture)}",
                                        Payuser = coupon.Ticketcode
                                    });
                                }

                            }
                        }




                        /*
                        foreach (var x in discountlist) {
                            var _paytype = "5";

                            if (x.DiscountCouponType == 1) {
                                _paytype = "6";
                                pay.Paycontent.Add(new IcConsumepayReq.PaycontentItem {
                                    Paytype = _paytype,
                                    Paymoney = x.DiscountCouponUseMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                                    Paytradeno = $"t{DateTime.Now.ToString("yyMMddHHmmssffff", CultureInfo.CurrentCulture)}",
                                    Payuser = $"{x.DiscountCouponId}"
                                });
                            } else {

                                var coupon = await _memberCouponService.FindAsync<ICasaMielSession>(x.DiscountCouponId).ConfigureAwait(false);
                                pay.Paycontent.Add(new IcConsumepayReq.PaycontentItem {
                                    Paytype = _paytype,
                                    Paymoney = x.DiscountCouponUseMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                                    Paytradeno = $"t{DateTime.Now.ToString("yyMMddHHmmssffff", CultureInfo.CurrentCulture)}",
                                    Payuser = coupon.Ticketcode
                                });
                            }
                        }
                        */
                        pay.Paycontent.Add(new IcConsumepayReq.PaycontentItem {
                            Paytype = payrecord.PayMethod == 4 ? "1" : payrecord.PayMethod.ToString(CultureInfo.CurrentCulture),
                            Paymoney = payrecord.Amount,
                            Paytradeno = OutTradeNO,
                            Payid = MchId
                        });
                        if (order.FreightMoney > 0) {
                            pay.Payfee = new List<IcConsumepayReq.PayfeeItem>{
                                new IcConsumepayReq.PayfeeItem {
                                    Feetype = "1",
                                    Fee = order.FreightMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                                    Description = "配送费"
                                } }
                            ;//配送费
                        }

                        var zmodel = await _icApiService.Icconsumepay(pay).ConfigureAwait(false);
                        logger.Trace($"icconsumepay,req:{JsonConvert.SerializeObject(pay)},rsp:{JsonConvert.SerializeObject(zmodel)}");
                        bool success = false;
                        if (zmodel.code == 0) {
                            var jobject = JsonConvert.DeserializeObject<JObject>(zmodel.content);
                            if (jobject != null && jobject["invoiceqrcode"] != null) {
                                var invoiceUrl = jobject["invoiceqrcode"].ToString();
                                logger.Trace($"invoiceUrl:{invoiceUrl}");
                                order.InvoiceUrl = invoiceUrl;
                            } else {
                                logger.Error($"Invoideurl:{zmodel.content}");
                            }
                            using (var uow = _session.UnitOfWork(IsolationLevel.Serializable)) {
                                order.OrderStatus = (int)OrderStatus.Paid;
                                order.PayTime = DateTime.Now;
                                order.PayMethod = payrecord.PayMethod;
                                success = await _order.OrderBaseUPdateAsync(order, uow).ConfigureAwait(true);
                                if (success) {
                                    await _order.UpdateOrderTakeStatus(order.OrderBaseId, 0, "", uow).ConfigureAwait(true);
                                    await paymentService.UpdateAsync(payrecord, uow).ConfigureAwait(true);

                                    Task task = Task.Run(async () => {
                                        var noticEntity = new NoticeBaseEntity() {
                                            RemindTime = DateTime.Now.AddMinutes(-1),
                                            CreateTime = DateTime.Now,
                                            RelationId = order.OrderBaseId,
                                            StoreId = order.StoreId,
                                            NoticeType = 0
                                        };
                                        await _notice.AddAsync(noticEntity, uow).ConfigureAwait(true);
                                    });
                                    
                                }
                            }
							
                            if (success) {
                                var info = "蛋糕订单支付";
                                if (payrecord.OperationMethod == (int)OperationMethod.Waimai) {
                                    info = "外卖订单支付";
                                }
                                if(payrecord.OperationMethod == (int)OperationMethod.Pre) {
                                    info = "预点单支付";
									try {
                                        var storeentity = await _storeService.GetByStoreIdAsync<ICasaMielSession>(order.StoreId).ConfigureAwait(false);
                                        var precommd = new PreOrderPaySucessSubscribeMessageCommand { Mobile = order.Mobile,OrderCode=payrecord.BillNO };
                                        precommd.Data = new string[] { order.TakeCode, storeentity?.StoreName, storeentity?.FullAddress, $"¥{payrecord.Amount.ToString("#", CultureInfo.CurrentCulture)}", "已下单" };
                                        await _mediator.Send(precommd).ConfigureAwait(false);

                                    } catch (Exception ex) {
                                        logger.Error($"PreOrderPaySucessSubscribeMessageCommand:{ex.StackTrace}");
                                    }
                                          }
                                var orderstatusrsp = await _storeApiService.CakeOrderChangeStatus(payrecord.BillNO, order.Mobile, 1, payrecord.PayMethod, "").ConfigureAwait(false);

                                logger.Trace($"CakeOrderChangeStatus:{JsonConvert.SerializeObject(orderstatusrsp)}");

                                var logdata = new UserLog { OPInfo = $"{info},支付方式:[{payrecord.Remark},支付金额{payrecord.Amount}，订单号：{payrecord.BillNO}", OPTime = DateTime.Now, UserName = payrecord.Mobile };
                                await _mediator.Publish(new UserLogNoticeCommand(logdata)).ConfigureAwait(false);
                                 
                            } else {
                                await Refund(payrecord).ConfigureAwait(false);
                            }
                            return true;
                        } else if (zmodel.code == 211) {
                            return true;
                        }
                        return true;

                    #region 全国配
                    case (int)OperationMethod.Mall://全国配
                        var _mcardno = "";
                        var mcardlist = await _memberCardService.GetListAsync<ICasaMielSession>(payrecord.Mobile).ConfigureAwait(false);
                        if (mcardlist != null && mcardlist.Count(c => c.IsBind == true) == 2) {
                            var vipcard = mcardlist.SingleOrDefault(c => c.IsBind == true && c.CardType != "3");
                            if (vipcard != null) {
                                _cardno = vipcard.CardNO;
                            }
                        }
                        if (string.IsNullOrEmpty(_mcardno)) {
                            foreach (var item in mcardlist) {
                                if (item.IsBind) {
                                    _cardno = item.CardNO;
                                    break;
                                }
                            }
                        }

                        payrecord.PayTime = DateTime.Now;
                        payrecord.OperationState = 1;
                        payrecord.OutTradeNo = OutTradeNO;
                        payrecord.MchId = MchId;
                        payrecord.State = 1;
                        payrecord.LastOperationTime = DateTime.Now;
                        var orderentity = await _order.GetByOrderCodeAsync<ICasaMielSession>(payrecord.BillNO).ConfigureAwait(false);
                        //var orderbase = new MWebOrderBaseRsp();
                        //var orderresult = await _mallService.GetOrderBase(payrecord.Mobile, payrecord.BillNO).ConfigureAwait(false);
                        if (orderentity == null) {
                            return false;
                        }

                        var orderdiscountlist = await _order.GetListByOrderBaseId<ICasaMielSession>(orderentity.OrderBaseId).ConfigureAwait(false);
                        //if (orderresult.Code != 0)
                        //{
                        //    return false;
                        //}
                        //orderbase = orderresult.Content;
                        var mpay = new IcConsumepayReq {
                            Shopid = _mallSettings.ShopId,
                            Tradeno = orderentity.IcTradeNO,
                            Phoneno = payrecord.Mobile,
                            Cardno = _mcardno,
                            Createinvoice = true
                        };

                        mpay.Paycontent = new List<IcConsumepayReq.PaycontentItem>();

                        foreach (var x in orderdiscountlist) {
                            var _paytype = "5";

                            if (x.DiscountCouponType == 1) {
                                _paytype = "6";
                                mpay.Paycontent.Add(new IcConsumepayReq.PaycontentItem {
                                    Paytype = _paytype,
                                    Paymoney = x.DiscountCouponUseMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                                    Paytradeno = $"t{DateTime.Now.ToString("yyMMddHHmmssffff", CultureInfo.CurrentCulture)}",
                                    Payuser = $"{x.DiscountCouponId}"
                                });
                            } else {

                                if (_apiname == "hgspApi") {
                                    var tlist = _memberCashCouponRepository.GetListAsnyc<ICasaMielSession>(payrecord.Mobile).GetAwaiter().GetResult();
                                    MemberCashCoupon cashentity = tlist.SingleOrDefault(t => t.TicketCode.Contains($"{x.DiscountCouponId}", StringComparison.CurrentCulture));
                                    if (cashentity != null) {
                                        mpay.Paycontent.Add(new IcConsumepayReq.PaycontentItem {
                                            Paytype = _paytype,
                                            Paymoney = x.DiscountCouponUseMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                                            Paytradeno = $"t{DateTime.Now.ToString("yyMMddHHmmssffff", CultureInfo.CurrentCulture)}",
                                            Payuser = cashentity.TicketCode
                                        });
                                    }
                                } else {
                                    var coupon = await _memberCouponService.FindAsync<ICasaMielSession>(x.DiscountCouponId).ConfigureAwait(false);
                                    mpay.Paycontent.Add(new IcConsumepayReq.PaycontentItem {
                                        Paytype = _paytype,
                                        Paymoney = x.DiscountCouponUseMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                                        Paytradeno = $"t{DateTime.Now.ToString("yyMMddHHmmssffff", CultureInfo.CurrentCulture)}",
                                        Payuser = coupon.Ticketcode
                                    });
                                }

                            }
                        }

                        //orderdiscountlist.ForEach((Action<Order_DiscountCouponEntity>)(x => {
                        //    var _paytype = "5";
                        //    if (x.DiscountCouponType == 1) {
                        //        _paytype = "6";
                        //        mpay.Paycontent.Add(new IcConsumepayReq.PaycontentItem {
                        //            Paytype = _paytype,
                        //            Paymoney = x.DiscountCouponUseMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                        //            Paytradeno = $"t{DateTime.Now.ToString("yyMMddHHmmssffff", CultureInfo.CurrentCulture)}",
                        //            Payuser = $"{x.DiscountCouponId}"
                        //        });
                        //    } else {
                        //        var tlist = _memberCashCouponRepository.GetListAsnyc<ICasaMielSession>(payrecord.Mobile).GetAwaiter().GetResult();
                        //        MemberCashCoupon cashentity = tlist.SingleOrDefault(t => t.TicketCode.Contains($"{x.DiscountCouponId}", StringComparison.CurrentCulture));
                        //        if (cashentity != null) {
                        //            mpay.Paycontent.Add(new IcConsumepayReq.PaycontentItem {
                        //                Paytype = _paytype,
                        //                Paymoney = x.DiscountCouponUseMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                        //                Paytradeno = $"t{DateTime.Now.ToString("yyMMddHHmmssffff", CultureInfo.CurrentCulture)}",
                        //                Payuser = cashentity.TicketCode
                        //            });
                        //        }

                        //    }
                        //}));
                        //if (orderentity.DiscountCouponId > 0)
                        //{
                        //    mpay.paycontent.Add(new IcConsumepayReq.Paycontent
                        //    {
                        //        paytype = "6",
                        //        paymoney = orderbase.DiscountCouponActualMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                        //        paytradeno = $"t{DateTime.Now.ToString("yyMMddHHmmssffff", CultureInfo.CurrentCulture)}",
                        //        payuser = $"{orderbase.DiscountCouponId}"
                        //    });
                        //}
                        if (orderentity.FreightMoney > 0) {
                            mpay.Payfee = new List<IcConsumepayReq.PayfeeItem>{
                                new IcConsumepayReq.PayfeeItem {
                                    Feetype = "1",
                                    Fee = orderentity.FreightMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                                    Description = "配送费"
                                } }
                            ;//配送费
                        }
                        mpay.Paycontent.Add(new IcConsumepayReq.PaycontentItem {
                            Paytype = payrecord.PayMethod == 4 ? "1" : payrecord.PayMethod.ToString(CultureInfo.CurrentCulture),
                            Paymoney = payrecord.Amount,
                            Paytradeno = OutTradeNO,
                            Payid = MchId
                        });
                        var mzmodel = await _icApiService.Icconsumepay(mpay).ConfigureAwait(false);
                        logger.Trace($"icconsumepay,req:{JsonConvert.SerializeObject(mpay)},rsp:{JsonConvert.SerializeObject(mzmodel)}");

                        if (mzmodel.code == 0) {
                            var jobject = JsonConvert.DeserializeObject<JObject>(mzmodel.content);
                            if (jobject != null && jobject["invoiceqrcode"] != null) {
                                var invoiceUrl = jobject["invoiceqrcode"].ToString();
                                logger.Trace($"Invoideurl:{invoiceUrl},ordercode:{orderentity.OrderCode}");
                                orderentity.InvoiceUrl = invoiceUrl;
                                //await _order.UpdateOrderInvoiceUrlByOrderCodeAsync<ICasaMielSession>(payrecord.BillNO, invoiceUrl).ConfigureAwait(false);
                            } else {
                                logger.Error($"Invoideurl:{mzmodel.content}");
                            }

                            var result = await _mallService.OrderChangeStatus(payrecord.BillNO, payrecord.Mobile, 1, payrecord.PayMethod, "").ConfigureAwait(false);
                            orderentity.OrderStatus = (int)OrderStatus.Paid;
                            orderentity.PayTime = DateTime.Now;
                            orderentity.PayMethod = payrecord.PayMethod;
                            using (var uow = _session.UnitOfWork(IsolationLevel.Serializable)) {
                                await paymentService.UpdateAsync(payrecord, uow).ConfigureAwait(false);
                                await _order.OrderBaseUPdateAsync(orderentity, uow).ConfigureAwait(false);
                            }

                            var logdata = new UserLog { OPInfo = $"全国配商城订单支付,支付方式:[{payrecord.Remark},支付金额{payrecord.Amount}，订单号：{payrecord.BillNO}", OPTime = DateTime.Now, UserName = payrecord.Mobile };
                            await _mediator.Publish(new UserLogNoticeCommand(logdata)).ConfigureAwait(false);
                            //await _userLogService.AddAsync<ICasaMielSession>(logdata).ConfigureAwait(false);
                            return true;


                        } else if (mzmodel.code == 211) {
                            var result = await _mallService.OrderChangeStatus(orderentity.OrderCode, payrecord.Mobile, 1, payrecord.PayMethod, "").ConfigureAwait(false);
                            if (result.Code == 0) {
                                using (var uow = _session.UnitOfWork(IsolationLevel.Serializable)) {
                                    await paymentService.UpdateAsync(payrecord, uow).ConfigureAwait(false);
                                }

                                var logdata = new UserLog { OPInfo = $"全国配商城订单支付,支付方式:[{payrecord.Remark},支付金额{payrecord.Amount}，订单号：{payrecord.BillNO}", OPTime = DateTime.Now, UserName = payrecord.Mobile };
                                await _mediator.Publish(new UserLogNoticeCommand(logdata)).ConfigureAwait(false);
                                // await _userLogService.AddAsync<ICasaMielSession>(logdata).ConfigureAwait(false);
                                return true;
                            } else {
                                return false;
                            }

                        } else {
                            return false;
                        }
                    #endregion

                    #region 团购
                    case (int)OperationMethod.GroupPurchase:

                        payrecord.PayTime = DateTime.Now;
                        payrecord.OperationState = 1;
                        payrecord.OutTradeNo = OutTradeNO;
                        payrecord.MchId = MchId;
                        payrecord.State = 1;
                        payrecord.LastOperationTime = DateTime.Now;

                        var rsp = await _storeApiService.ChangeGrouponOrderStatusAsync(payrecord.BillNO, payrecord.Mobile, 1, payrecord.PayMethod).ConfigureAwait(false);
                        if (rsp.Code == 0) {

                            using (var uow = _session.UnitOfWork(IsolationLevel.Serializable)) {
                                await paymentService.UpdateAsync(payrecord, uow).ConfigureAwait(false);
                            }
                            var SendTicketCmd = new SendTicketCommand(payrecord.BillNO, 1,1);
                            await _mediator.Send(SendTicketCmd).ConfigureAwait(false);
                            return true;
                        }

                        return false;
                        #endregion
                }
                #region MyRegion
                /*
                if (payrecord.OperationMethod == 1)//充值
                {

                        try
                    {
                        Zmodel tmodel = await _icApiService.IcCharge(payrecord.BillNO, payrecord.Amount, payrecord.PayMethod, OutTradeNO, MchId, payrecord.ShopId);
                        if (tmodel.code == 0 || tmodel.code == 180)// || tmodel.code == 261充值记录失败
                        {
                            if (tmodel.code == 0)
                            {
                                var rnt = JsonConvert.DeserializeObject<dynamic>(tmodel.content);
                                payrecord.IcTradeNO = rnt.tradeno;
                                payrecord.largessmoney = rnt.largessmoney;
                                payrecord.PayTime = DateTime.Now;
                                payrecord.OperationState = 1;
                                payrecord.OutTradeNo = OutTradeNO;
                                payrecord.MchId = MchId;
                                payrecord.State = 1;
                                payrecord.LastOperationTime = DateTime.Now;
                                payrecord.LastOperationTime = DateTime.Now;
                                //payrecord.Remark = "小程序支付";
                                //_paymentRecordRepository.Update(payrecord, 0);
                                await paymentService.UpdateAsync<ICasaMielSession>(payrecord);
                                var logdata = new Domain.UserLog { Url = "", OPInfo = $"会员充值，卡号[{payrecord.BillNO}],金额{payrecord.Amount}", OPTime = DateTime.Now, UserName = payrecord.Mobile };
                                await _userLogService.AddAsync<ICasaMielSession>(logdata);
                            }
                            return true;
                        }
                        else
                        {
                            Console.WriteLine(tmodel.msg);
                            logger.Error("会员充值失败：" + JsonConvert.SerializeObject(tmodel));
                            return false;
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex.StackTrace);
                        return false;
                    }
                }
                else if (payrecord.OperationMethod == 2)
                {
                    var ordere = await _storeApiService.GetOrderByOrderCodeAsync(payrecord.BillNO, payrecord.Mobile);
                    //orderasync.Wait();
                    //var ordere = orderasync.Result;
                    var order = await _storeService.GetByOrderCodeAsync<ICasaMielSession>(payrecord.BillNO, payrecord.Mobile);

                    //if (ordere.DiscountCouponId > 0)
                    //{

                    //var a = _iicApiService.Geticticket(new TicticketDto { cardno = ordere.CardNo, pagesize = 200, state = 2, pageindex = 1 });
                    //a.Wait();
                    //var zmodel = a.Result;
                    //if (zmodel.code == 0)
                    //{
                    //    var list = JsonConvert.DeserializeObject<TicketItemRoot>(zmodel.content);
                    //    var ticket = list.tickets.Where(t => t.ticketid == ordere.DiscountCouponId).SingleOrDefault();
                    //    if (ticket == null)
                    //    {


                    //    }
                    //}

                    var _cardno = "";
                    var cardlist = await _memberCardService.GetCardListAsyncByMobile<ICasaMielSession>(payrecord.Mobile);

                    if (cardlist != null && cardlist.Where(c => c.IsBind == true).Count() == 2)
                    {
                        var vipcard = cardlist.Where(c => c.IsBind == true && c.CardType != "3").SingleOrDefault();
                        if (vipcard != null)
                        {
                            _cardno = vipcard.CardNo;
                        }
                    }
                    if (string.IsNullOrEmpty(_cardno))
                    {
                        foreach (var item in cardlist)
                        {
                            if (item.IsBind)
                            {
                                _cardno = item.CardNo;
                                break;
                            }
                        }
                    }

                    var pay = new IcConsumepayDto
                    {
                        shopid = ordere.StoreRelationId,
                        tradeno = ordere.IcTradeNo,
                        phoneno = payrecord.Mobile,
                        cardno = _cardno
                    };
                    pay.paycontent = new List<IcConsumepayDto.Paycontent>();


                    if (ordere.DiscountCouponId > 0)
                    {
                        pay.paycontent.Add(new IcConsumepayDto.Paycontent
                        {
                            paytype = "6",
                            paymoney = ordere.DiscountCouponActualMoney.ToString().ToDouble(0),
                            paytradeno = $"t{DateTime.Now.ToString("yyMMddHHmmssffff")}",
                            payuser = $"{ordere.DiscountCouponId}"
                        });
                    }
                    pay.paycontent.Add(new IcConsumepayDto.Paycontent
                    {
                        paytype = payrecord.PayMethod == 4 ? "1" : payrecord.PayMethod.ToString(),
                        paymoney = payrecord.Amount,
                        paytradeno = OutTradeNO,
                        payid = MchId
                    });
                    logger.Trace($"icconsumepay:{JsonConvert.SerializeObject(pay)}");
                    var zmodel = await _icApiService.icconsumepay(pay);
                    if (zmodel.code == 0)
                    {
                        //payment.PayMethod = data.payMethod;
                        //payment.PayTime = DateTime.Now;
                        //payment.State = 1;
                        //payment.OperationState = 1;
                        using (var uow = _session.UnitOfWork(IsolationLevel.Serializable))
                        {
                            order.OrderStatus = 2;
                            order.PayTime = DateTime.Now;
                            await _storeService.OrderBaseUPdateAsync(order, uow);

                            await _storeService.UpdateOrderTakeStatus(order.OrderBaseId, 0, "", uow);

                            payrecord.PayTime = DateTime.Now;
                            payrecord.OperationState = 1;
                            payrecord.OutTradeNo = OutTradeNO;
                            payrecord.MchId = MchId;
                            payrecord.State = 1;
                            payrecord.LastOperationTime = DateTime.Now;

                            await paymentService.UpdateAsync(payrecord, uow);
                            var noticEntity = new Notice_baseEntity()
                            {
                                RemindTime = DateTime.Now.AddMinutes(-1),
                                CreateTime = DateTime.Now,
                                RelationId = order.OrderBaseId,
                                StoreId = order.StoreId,
                                NoticeType = 0
                            };
                            await _storeService.AddNoticeAsync(noticEntity, uow);
                            var logdata = new UserLog { OPInfo = $"蛋糕订单支付,支付方式:[{payrecord.Remark},支付金额{payrecord.Amount}，订单号：{payrecord.BillNO}", OPTime = DateTime.Now, UserName = payrecord.Mobile };
                            await _userLogService.AddAsync<ICasaMielSession>(logdata);
                        }
                        var result = await _storeApiService.SendOrderNotice(order.OrderCode);
                        logger.Trace($"SendOrderNotice:{result}");
                        //return new JsonResult(new { code = 0, content = entity, payMethod = payment.PayMethod, payed = true });
                    }
                    else if (zmodel.code == 211)
                    {
                        return true;
                    }
                    else
                    {
                        logger.Trace($"{JsonConvert.SerializeObject(zmodel)}");
                        return false;

                    }
                    //}
                }
                */
                #endregion
            }
            return true;
        }


        private async Task Refund(PaymentRecord payinfo)
        {
            //var payinfo = await paymentService.FindAsync<ICasaMielSession>(TradeNO).ConfigureAwait(false);
            //if (payinfo == null) {
            //    return;// new Zmodel { code = 0, msg = "未支付订单" };
            //}

            string OutRefundNo = "R" + DateTime.Now.ToString("yyyyMMddHHmmssfff", CultureInfo.CurrentCulture);
            //  var re = await Consumeback(entity, payinfo);

            switch (payinfo.PayMethod) {
                case 1://appwechatpay
                    var gateway2 = new PaySharp.Wechatpay.Merchant {
                        AppId = Configuration.GetSection("WxPayAppSettings").GetValue<string>("AppId"),
                        MchId = Configuration.GetSection("WxPayAppSettings").GetValue<string>("MchId"),// "1498771272",//1233410002",
                        Key = Configuration.GetSection("WxPayAppSettings").GetValue<string>("Key"),
                        AppSecret = Configuration.GetSection("WxPayAppSettings").GetValue<string>("AppSecret"),// "f7ab7484a6bd1df17ca2e7cc35604459",
                        SslCertPath = Configuration.GetSection("WxPayAppSettings").GetValue<string>("SslCertPath"),//"Certs/apiclient_cert.p12",
                        SslCertPassword = Configuration.GetSection("WxPayAppSettings").GetValue<string>("SslCertPassword"),// "1233410002",
                        NotifyUrl = Configuration.GetSection("WxPayAppSettings").GetValue<string>("NotifyUrl")// _settings.AppWxpayNotify,// "http://localhost:61337/Notify"
                    };
                    var request1 = new RefundRequest();
                    request1.AddGatewayData(new RefundModel() {
                        TradeNo = payinfo.OutTradeNo,
                        RefundAmount = (payinfo.Amount * 100).ToInt32(0),
                        RefundDesc = "",
                        RefundAccount = "REFUND_SOURCE_UNSETTLED_FUNDS",
                        OutRefundNo = payinfo.TradeNo.Replace("C", "R", StringComparison.OrdinalIgnoreCase),
                        TotalAmount = (payinfo.Amount * 100).ToInt32(0),
                        OutTradeNo = payinfo.TradeNo
                    });
                    WechatpayGateway ga1 = new WechatpayGateway(gateway2);
                    var response1 = ga1.Execute(request1);
                    logger.Trace($"Refund:{JsonConvert.SerializeObject(response1)}");
                    if (response1.ResultCode == "SUCCESS") {
                        var en = await paymentService.FindAsync<ICasaMielSession>(payinfo.TradeNo.Replace("C", "R", StringComparison.OrdinalIgnoreCase)).ConfigureAwait(false);
                        if (en == null) {
                            var paymentr = new PaymentRecord() {
                                Mobile = payinfo.Mobile,
                                BillNO = payinfo.TradeNo,
                                OperationMethod = 3,
                                Amount = payinfo.Amount,
                                CreateTime = DateTime.Now,
                                TradeNo = payinfo.TradeNo.Replace("C", "R", StringComparison.OrdinalIgnoreCase),
                                OutTradeNo = response1.RefundNo,
                                PayMethod = 4,
                                MchId = payinfo.MchId,
                                State = 1,
                                LastOperationTime = DateTime.Now,
                                OperationState = 1,
                                Remark = payinfo.Remark
                            };
                            await paymentService.AddAsync<ICasaMielSession>(paymentr).ConfigureAwait(false);
                        }
                        //var re = await Consumeback(entity, payinfo);

                    } else {
                        logger.Error($"Refund{payinfo.TradeNo},:{JsonConvert.SerializeObject(response1)}");
                    }

                    break;
                case 2://alipay
                    var merchant = new PaySharp.Alipay.Merchant() {
                        AppId = Configuration.GetSection("AlipaySettings").GetValue<string>("AppId"),// "2018012302035911",
                        NotifyUrl = Configuration.GetSection("AlipaySettings").GetValue<string>("NotifyUrl"),//"http://xiaoha.zicp.net:10154/Notify",//
                        ReturnUrl = Configuration.GetSection("AlipaySettings").GetValue<string>("ReturnUrl"),//"http://xiaoha.zicp.net:10154/Notify1",//
                        AlipayPublicKey = Configuration.GetSection("AlipaySettings").GetValue<string>("AlipayPublicKey"),
                        Privatekey = Configuration.GetSection("AlipaySettings").GetValue<string>("Privatekey")
                    };
                    var alipayrequest = new PaySharp.Alipay.Request.RefundRequest();
                    alipayrequest.AddGatewayData(new PaySharp.Alipay.Domain.RefundModel() {
                        TradeNo = payinfo.OutTradeNo,
                        RefundAmount = payinfo.Amount,
                        RefundReason = "",
                        OutRefundNo = payinfo.TradeNo + "1",
                        OutTradeNo = payinfo.TradeNo

                    });
                    PaySharp.Alipay.AlipayGateway gateway = new PaySharp.Alipay.AlipayGateway(merchant);
                    var alipayresponse = gateway.Execute(alipayrequest);
                    if (alipayresponse.Code == "10000") {
                        var paymentr = new PaymentRecord() {
                            Mobile = payinfo.Mobile,
                            BillNO = payinfo.TradeNo,
                            OperationMethod = 3,
                            Amount = payinfo.Amount,
                            CreateTime = DateTime.Now,
                            TradeNo = OutRefundNo,
                            OutTradeNo = alipayresponse.TradeNo,
                            PayMethod = 2,
                            MchId = payinfo.MchId,
                            State = 1,
                            LastOperationTime = DateTime.Now,
                            OperationState = 1,
                            Remark = payinfo.Remark
                        };
                        await paymentService.AddAsync<ICasaMielSession>(paymentr).ConfigureAwait(false);
                        logger.Trace($"refund:{JsonConvert.SerializeObject(alipayresponse)}");
                        //var re = await Consumeback(entity, payinfo);

                    } else {
                        logger.Error($"Refund{payinfo.TradeNo},:{JsonConvert.SerializeObject(alipayresponse)}");
                    }

                    break;
                case 4:
                    var _miniappsetting = _listminiAppSettings.Where(c => c.MchId == payinfo.MchId).FirstOrDefault();
                    var gateway1 = new PaySharp.Wechatpay.Merchant {
                        AppId = _miniappsetting.appid,
                        MchId = _miniappsetting.MchId,// "1498771272",//1233410002",
                        Key = _miniappsetting.Key,//"10adc3549ba6abe56e056f23f83e71dA",
                        AppSecret = _miniappsetting.AppSecret,// "f7ab7484a6bd1df17ca2e7cc35604459",
                        SslCertPath = _miniappsetting.SslCertPath,//"Certs/apiclient_cert.p12",
                        SslCertPassword = _miniappsetting.SslCertPassword,// "1233410002",
                        NotifyUrl = _miniappsetting.NotifyUrl + "/" + _miniappsetting.appid// _settings.AppWxpayNotify,// "http://localhost:61337/Notify"
                    };
                    logger.Trace($"_miniAppSettings{JsonConvert.SerializeObject(_listminiAppSettings)}");
                    var request = new RefundRequest();
                    request.AddGatewayData(new RefundModel() {
                        TradeNo = payinfo.OutTradeNo,
                        RefundAmount = (payinfo.Amount * 100).ToInt32(0),
                        RefundDesc = "",
                        RefundAccount = "REFUND_SOURCE_UNSETTLED_FUNDS",
                        OutRefundNo = payinfo.TradeNo.Replace("C", "R"),
                        TotalAmount = (payinfo.Amount * 100).ToInt32(0),
                        OutTradeNo = payinfo.TradeNo
                    });
                    WechatpayGateway ga = new WechatpayGateway(gateway1);
                    if (!string.IsNullOrEmpty(_miniappsetting.GatewayUrl)) {
                        ga.GatewayUrl = _miniappsetting.GatewayUrl;
                    }

                    var response = ga.Execute(request);
                    logger.Trace($"refund:{JsonConvert.SerializeObject(response)}");
                    if (response.ResultCode == "SUCCESS") {
                        var en = await paymentService.FindAsync<ICasaMielSession>(payinfo.TradeNo.Replace("C", "R", StringComparison.CurrentCultureIgnoreCase)).ConfigureAwait(false);
                        if (en == null) {
                            var paymentr = new PaymentRecord() {
                                Mobile = payinfo.Mobile,
                                BillNO = payinfo.TradeNo,
                                OperationMethod = 3,
                                Amount = payinfo.Amount,
                                CreateTime = DateTime.Now,
                                TradeNo = payinfo.TradeNo.Replace("C", "R", StringComparison.CurrentCultureIgnoreCase),
                                OutTradeNo = response.RefundNo,
                                PayMethod = 4,
                                MchId = payinfo.MchId,
                                State = 1,
                                LastOperationTime = DateTime.Now,
                                OperationState = 1,
                                Remark = payinfo.Remark
                            };
                            await paymentService.AddAsync<ICasaMielSession>(paymentr).ConfigureAwait(false);
                        }
                    } else {
                        logger.Error($"Refund{payinfo.TradeNo},:{JsonConvert.SerializeObject(response)}");
                    }
                    break;
                default:
                    break;
            }
        }
    }
}
